<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>Zookeeper | 阿毛的博客</title><meta name="keywords" content="ZooKeeper"><meta name="author" content="myl"><meta name="copyright" content="myl"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="Zookeeper1)初识 Zookeeper1.1)Zookeeper概念•Zookeeper 是 Apache Hadoop 项目下的一个子项目，是一个树形目录服务。 •Zookeeper 翻译过来就是 动物园管理员，他是用来管 Hadoop（大象）、Hive(蜜蜂)、Pig(小 猪)的管理员。简称zk •Zookeeper 是一个分布式的、开源的分布式应用程序的协调服务。 •Zookeepe">
<meta property="og:type" content="article">
<meta property="og:title" content="Zookeeper">
<meta property="og:url" content="https://gitee.com/tgreen/myl-mm.git/2022/05/09/zookeeper%E8%AE%B2%E4%B9%89md/index.html">
<meta property="og:site_name" content="阿毛的博客">
<meta property="og:description" content="Zookeeper1)初识 Zookeeper1.1)Zookeeper概念•Zookeeper 是 Apache Hadoop 项目下的一个子项目，是一个树形目录服务。 •Zookeeper 翻译过来就是 动物园管理员，他是用来管 Hadoop（大象）、Hive(蜜蜂)、Pig(小 猪)的管理员。简称zk •Zookeeper 是一个分布式的、开源的分布式应用程序的协调服务。 •Zookeepe">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://itcast-haoke-myl.oss-cn-beijing.aliyuncs.com/images/2022/04/13/cat1.jpg">
<meta property="article:published_time" content="2022-05-09T09:00:24.182Z">
<meta property="article:modified_time" content="2022-05-09T11:36:21.815Z">
<meta property="article:author" content="myl">
<meta property="article:tag" content="ZooKeeper">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://itcast-haoke-myl.oss-cn-beijing.aliyuncs.com/images/2022/04/13/cat1.jpg"><link rel="shortcut icon" href="/myl-mm/img/favicon.png"><link rel="canonical" href="https://gitee.com/tgreen/myl-mm.git/2022/05/09/zookeeper%E8%AE%B2%E4%B9%89md/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/myl-mm/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/myl-mm/',
  algolia: undefined,
  localSearch: undefined,
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery@2/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery@2/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'Zookeeper',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-05-09 19:36:21'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><meta name="generator" content="Hexo 5.4.2"></head><body><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/myl-mm/archives/"><div class="headline">文章</div><div class="length-num">22</div></a><a href="/myl-mm/tags/"><div class="headline">标签</div><div class="length-num">11</div></a><a href="/myl-mm/categories/"><div class="headline">分类</div><div class="length-num">7</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/myl-mm/"><i class="fa-fw fas fa-home"></i><span> Home</span></a></div><div class="menus_item"><a class="site-page" href="/myl-mm/tags/"><i class="fa-fw fas fa-tags"></i><span> Tags</span></a></div><div class="menus_item"><a class="site-page" href="/myl-mm/categories/"><i class="fa-fw fas fa-folder-open"></i><span> Categories</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://itcast-haoke-myl.oss-cn-beijing.aliyuncs.com/images/2022/04/13/long1.jpg')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/myl-mm/">阿毛的博客</a></span><div id="menus"><div class="menus_items"><div class="menus_item"><a class="site-page" href="/myl-mm/"><i class="fa-fw fas fa-home"></i><span> Home</span></a></div><div class="menus_item"><a class="site-page" href="/myl-mm/tags/"><i class="fa-fw fas fa-tags"></i><span> Tags</span></a></div><div class="menus_item"><a class="site-page" href="/myl-mm/categories/"><i class="fa-fw fas fa-folder-open"></i><span> Categories</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">Zookeeper</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2022-05-09T09:00:24.182Z" title="发表于 2022-05-09 17:00:24">2022-05-09</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2022-05-09T11:36:21.815Z" title="更新于 2022-05-09 19:36:21">2022-05-09</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/myl-mm/categories/ZooKeeper/">ZooKeeper</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="Zookeeper"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="Zookeeper"><a href="#Zookeeper" class="headerlink" title="Zookeeper"></a>Zookeeper</h1><h2 id="1-初识-Zookeeper"><a href="#1-初识-Zookeeper" class="headerlink" title="1)初识 Zookeeper"></a>1)初识 Zookeeper</h2><h3 id="1-1-Zookeeper概念"><a href="#1-1-Zookeeper概念" class="headerlink" title="1.1)Zookeeper概念"></a>1.1)Zookeeper概念</h3><p>•Zookeeper 是 Apache Hadoop 项目下的一个子项目，是一个树形目录服务。</p>
<p>•Zookeeper 翻译过来就是 动物园管理员，他是用来管 Hadoop（大象）、Hive(蜜蜂)、Pig(小 猪)的管理员。简称zk</p>
<p>•Zookeeper 是一个分布式的、开源的分布式应用程序的协调服务。</p>
<p>•Zookeeper 提供的主要功能包括：</p>
<p>•配置管理</p>
<p>•分布式锁</p>
<p>•集群管理</p>
<p><img src="/myl-mm/assets%5C1592054580488.png" alt="1592054580488"></p>
<p><img src="/myl-mm/assets%5C1592054603167.png" alt="1592054603167"></p>
<h2 id="2-ZooKeeper-安装与配置"><a href="#2-ZooKeeper-安装与配置" class="headerlink" title="2)ZooKeeper 安装与配置"></a>2)ZooKeeper 安装与配置</h2><h3 id="2-1-下载安装"><a href="#2-1-下载安装" class="headerlink" title="2.1) 下载安装"></a>2.1) 下载安装</h3><h4 id="2-1-1、环境准备"><a href="#2-1-1、环境准备" class="headerlink" title="2.1.1、环境准备"></a><strong>2.1.1、环境准备</strong></h4><p>ZooKeeper服务器是用Java创建的，它运行在JVM之上。需要安装JDK 7或更高版本。</p>
<h4 id="2-1-2、上传"><a href="#2-1-2、上传" class="headerlink" title="2.1.2、上传"></a><strong>2.1.2、上传</strong></h4><p>将下载的ZooKeeper放到&#x2F;opt&#x2F;ZooKeeper目录下</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">上传zookeeper alt+p</span></span><br><span class="line">put f:/setup/apache-zookeeper-3.5.6-bin.tar.gz</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">打开 opt目录</span></span><br><span class="line">cd /opt</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">创建zooKeeper目录</span></span><br><span class="line">mkdir  zooKeeper</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">将zookeeper安装包移动到 /opt/zooKeeper</span></span><br><span class="line">mv apache-zookeeper-3.5.6-bin.tar.gz /opt/zookeeper/</span><br></pre></td></tr></table></figure>

<h4 id="2-1-3、解压"><a href="#2-1-3、解压" class="headerlink" title="2.1.3、解压"></a><strong>2.1.3、解压</strong></h4><p>将tar包解压到&#x2F;opt&#x2F;zookeeper目录下</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tar -zxvf apache-ZooKeeper-3.5.6-bin.tar.gz </span><br></pre></td></tr></table></figure>

<h3 id="2-2-配置启动"><a href="#2-2-配置启动" class="headerlink" title="2.2) 配置启动"></a>2.2) 配置启动</h3><h4 id="2-2-1、配置zoo-cfg"><a href="#2-2-1、配置zoo-cfg" class="headerlink" title="2.2.1、配置zoo.cfg"></a><strong>2.2.1、配置zoo.cfg</strong></h4><p>进入到conf目录拷贝一个zoo_sample.cfg并完成配置</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">进入到conf目录</span></span><br><span class="line">cd /opt/zooKeeper/apache-zooKeeper-3.5.6-bin/conf/</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">拷贝</span></span><br><span class="line">cp  zoo_sample.cfg  zoo.cfg</span><br></pre></td></tr></table></figure>



<p>修改zoo.cfg</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">打开目录</span></span><br><span class="line">cd /opt/zooKeeper/</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">创建zooKeeper存储目录</span></span><br><span class="line">mkdir  zkdata</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">修改zoo.cfg</span></span><br><span class="line">vim /opt/zooKeeper/apache-zooKeeper-3.5.6-bin/conf/zoo.cfg</span><br></pre></td></tr></table></figure>

<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%AE%B2%E4%B9%89/assets/1577548250377.png" alt="1577548250377"></p>
<p>修改存储目录：dataDir&#x3D;&#x2F;opt&#x2F;zookeeper&#x2F;zkdata</p>
<h4 id="2-2-2、启动ZooKeeper"><a href="#2-2-2、启动ZooKeeper" class="headerlink" title="2.2.2、启动ZooKeeper"></a><strong>2.2.2、启动ZooKeeper</strong></h4><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">cd /opt/zooKeeper/apache-zooKeeper-3.5.6-bin/bin/</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">启动</span></span><br><span class="line"> ./zkServer.sh  start</span><br></pre></td></tr></table></figure>

<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%AE%B2%E4%B9%89/assets/1577548052037.png" alt="1577548052037"></p>
<p>看到上图表示ZooKeeper成功启动</p>
<p><strong>3、查看ZooKeeper状态</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./zkServer.sh status</span><br></pre></td></tr></table></figure>

<p>zookeeper启动成功。standalone代表zk没有搭建集群，现在是单节点</p>
<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%AE%B2%E4%B9%89/assets/1577548175232.png" alt="1577548175232"></p>
<p>zookeeper没有启动</p>
<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%AE%B2%E4%B9%89/assets/1577548112773.png" alt="1577548112773"></p>
<h3 id=""><a href="#" class="headerlink" title=""></a></h3><h2 id="3-ZooKeeper-命令操作"><a href="#3-ZooKeeper-命令操作" class="headerlink" title="3)ZooKeeper 命令操作"></a>3)ZooKeeper 命令操作</h2><h3 id="3-1-Zookeeper命令操作数据模型"><a href="#3-1-Zookeeper命令操作数据模型" class="headerlink" title="3.1)Zookeeper命令操作数据模型"></a>3.1)Zookeeper命令操作数据模型</h3><p>•ZooKeeper 是一个树形目录服务,其数据模型和Unix的文件系统目录树很类似，拥有一个层次化结构。</p>
<p>•这里面的每一个节点都被称为： ZNode，每个节点上都会保存自己的数据和节点信息。 </p>
<p>• 节点可以拥有子节点，同时也允许少量（1MB）数据存储在该节点之下。</p>
<p>•节点可以分为四大类：</p>
<p>•PERSISTENT 持久化节点 </p>
<p>•EPHEMERAL 临时节点 ：-e</p>
<p>•PERSISTENT_SEQUENTIAL 持久化顺序节点 ：-s</p>
<p>•EPHEMERAL_SEQUENTIAL 临时顺序节点  ：-es</p>
<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%AE%B2%E4%B9%89/assets/1592054828485.png" alt="1592054828485"></p>
<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%AE%B2%E4%B9%89/assets/1592054844023.png" alt="1592054844023"></p>
<h3 id="3-2-Zookeeper命令操作服务端命令"><a href="#3-2-Zookeeper命令操作服务端命令" class="headerlink" title="3.2)Zookeeper命令操作服务端命令"></a><strong>3.2)Zookeeper命令操作服务端命令</strong></h3><p>•启动 ZooKeeper 服务: .&#x2F;zkServer.sh start</p>
<p>•查看 ZooKeeper 服务状态: .&#x2F;zkServer.sh status</p>
<p>•停止 ZooKeeper 服务: .&#x2F;zkServer.sh stop </p>
<p>•重启 ZooKeeper 服务: .&#x2F;zkServer.sh restart </p>
<p><img src="/myl-mm/assets%5C1592055088686.png" alt="1592055088686"></p>
<h3 id="3-3-Zookeeper客户端常用命令"><a href="#3-3-Zookeeper客户端常用命令" class="headerlink" title="3.3)Zookeeper客户端常用命令"></a><strong>3.3)Zookeeper客户端常用命令</strong></h3><p>•连接ZooKeeper服务端</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./zkCli.sh –server ip:port</span><br></pre></td></tr></table></figure>

<p>•断开连接</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">quit</span><br></pre></td></tr></table></figure>

<p>•查看命令帮助</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">help</span><br></pre></td></tr></table></figure>

<p>•显示指定目录下节点</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ls 目录</span><br></pre></td></tr></table></figure>

<p>•创建节点</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">create /节点path value</span><br></pre></td></tr></table></figure>

<p>•获取节点值</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">get /节点path</span><br></pre></td></tr></table></figure>

<p>•设置节点值</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">set /节点path value</span><br></pre></td></tr></table></figure>

<p>•删除单个节点</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">delete /节点path</span><br></pre></td></tr></table></figure>

<p>•删除带有子节点的节点</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">deleteall /节点path</span><br></pre></td></tr></table></figure>

<p><img src="/myl-mm/assets%5C1592055332198.png" alt="1592055332198"></p>
<p><img src="/myl-mm/assets%5C1592055345400.png" alt="1592055345400"></p>
<h3 id="3-4-客户端命令-创建临时有序节点"><a href="#3-4-客户端命令-创建临时有序节点" class="headerlink" title="3.4)客户端命令-创建临时有序节点"></a>3.4)客户端命令-创建临时有序节点</h3><p>•创建临时节点</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">create -e /节点path value</span><br></pre></td></tr></table></figure>

<p>•创建顺序节点</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">create -s /节点path value</span><br></pre></td></tr></table></figure>

<p>•查询节点详细信息</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ls –s /节点path </span><br></pre></td></tr></table></figure>

<p>•czxid：节点被创建的事务ID </p>
<p>•ctime: 创建时间 </p>
<p>•mzxid: 最后一次被更新的事务ID </p>
<p>•mtime: 修改时间 </p>
<p>•pzxid：子节点列表最后一次被更新的事务ID</p>
<p>•cversion：子节点的版本号 </p>
<p>•dataversion：数据版本号 </p>
<p>•aclversion：权限版本号 </p>
<p>•ephemeralOwner：用于临时节点，代表临时节点的事务ID，如果为持久节点则为0 </p>
<p>•dataLength：节点存储的数据的长度 </p>
<p>•numChildren：当前节点的子节点个数 </p>
<p><img src="/myl-mm/assets%5C1592055462588.png" alt="1592055462588"></p>
<h2 id="4-ZooKeeper-JavaAPI-操作"><a href="#4-ZooKeeper-JavaAPI-操作" class="headerlink" title="4)ZooKeeper JavaAPI 操作"></a>4)ZooKeeper JavaAPI 操作</h2><h3 id="4-1-urator介绍"><a href="#4-1-urator介绍" class="headerlink" title="4.1)urator介绍"></a>4.1)urator介绍</h3><p>•Curator 是 Apache ZooKeeper 的Java客户端库。</p>
<p>•常见的ZooKeeper Java API ：</p>
<p>•原生Java API</p>
<p>•ZkClient</p>
<p>•Curator</p>
<p>•Curator 项目的目标是简化 ZooKeeper 客户端的使用。</p>
<p>•Curator 最初是 Netfix 研发的,后来捐献了 Apache 基金会,目前是 Apache 的顶级项目。</p>
<p>•官网：<a target="_blank" rel="noopener" href="http://curator.apache.org/">http://curator.apache.org/</a></p>
<h3 id="4-2-JavaAPI操作建立连接"><a href="#4-2-JavaAPI操作建立连接" class="headerlink" title="4.2)JavaAPI操作建立连接"></a>4.2)JavaAPI操作建立连接</h3><p>1，搭建项目</p>
<p>创建项目curator-zk</p>
<p>引入pom和日志文件</p>
<p>资料文件夹下pom.xml和log4j.properties</p>
<p><img src="/myl-mm/assets%5C1592055569716.png" alt="1592055569716"></p>
<p>2、创建测试类，使用curator连接zookeeper</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Before</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testConnect</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="comment">//重试策略</span></span><br><span class="line">    <span class="type">RetryPolicy</span> <span class="variable">retryPolicy</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ExponentialBackoffRetry</span>(<span class="number">3000</span>, <span class="number">10</span>);</span><br><span class="line">    <span class="comment">//2.第二种方式</span></span><br><span class="line">    <span class="comment">//CuratorFrameworkFactory.builder();</span></span><br><span class="line">    client = CuratorFrameworkFactory.builder()</span><br><span class="line">        .connectString(<span class="string">&quot;192.168.200.130:2181&quot;</span>)</span><br><span class="line">        .sessionTimeoutMs(<span class="number">60</span> * <span class="number">1000</span>)</span><br><span class="line">        .connectionTimeoutMs(<span class="number">15</span> * <span class="number">1000</span>)</span><br><span class="line">        .retryPolicy(retryPolicy)</span><br><span class="line">        .namespace(<span class="string">&quot;itheima&quot;</span>)</span><br><span class="line">        .build();</span><br><span class="line">    <span class="comment">//开启连接</span></span><br><span class="line">    client.start();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="4-3-Zookeeper-JavaAPI操作-创建节点"><a href="#4-3-Zookeeper-JavaAPI操作-创建节点" class="headerlink" title="4.3)Zookeeper JavaAPI操作-创建节点"></a>4.3)Zookeeper JavaAPI操作-创建节点</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 创建节点：create 持久 临时 顺序 数据</span></span><br><span class="line"><span class="comment">* 1. 基本创建 ：create().forPath(&quot;&quot;)</span></span><br><span class="line"><span class="comment">* 2. 创建节点 带有数据:create().forPath(&quot;&quot;,data)</span></span><br><span class="line"><span class="comment">* 3. 设置节点的类型：create().withMode().forPath(&quot;&quot;,data)</span></span><br><span class="line"><span class="comment">* 4. 创建多级节点  /app1/p1 ：create().creatingParentsIfNeeded().forPath(&quot;&quot;,data)</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testCreate</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">//2. 创建节点 带有数据</span></span><br><span class="line">    <span class="comment">//如果创建节点，没有指定数据，则默认将当前客户端的ip作为数据存储</span></span><br><span class="line">    <span class="type">String</span> <span class="variable">path</span> <span class="operator">=</span> client.create().forPath(<span class="string">&quot;/app2&quot;</span>, <span class="string">&quot;hehe&quot;</span>.getBytes());</span><br><span class="line">    System.out.println(path);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testCreate2</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">//1. 基本创建</span></span><br><span class="line">    <span class="comment">//如果创建节点，没有指定数据，则默认将当前客户端的ip作为数据存储</span></span><br><span class="line">    <span class="type">String</span> <span class="variable">path</span> <span class="operator">=</span> client.create().forPath(<span class="string">&quot;/app1&quot;</span>);</span><br><span class="line">    System.out.println(path);</span><br><span class="line">&#125;</span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testCreate3</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">//3. 设置节点的类型</span></span><br><span class="line">    <span class="comment">//默认类型：持久化</span></span><br><span class="line">    <span class="type">String</span> <span class="variable">path</span> <span class="operator">=</span> client.create().withMode(CreateMode.EPHEMERAL).forPath(<span class="string">&quot;/app3&quot;</span>);</span><br><span class="line">    System.out.println(path);</span><br><span class="line">&#125;</span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testCreate4</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">//4. 创建多级节点  /app1/p1</span></span><br><span class="line">    <span class="comment">//creatingParentsIfNeeded():如果父节点不存在，则创建父节点</span></span><br><span class="line">    <span class="type">String</span> <span class="variable">path</span> <span class="operator">=</span> client.create().creatingParentsIfNeeded().forPath(<span class="string">&quot;/app4/p1&quot;</span>);</span><br><span class="line">    System.out.println(path);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="4-4-ZookeeperJavaAPI操作-查询节点"><a href="#4-4-ZookeeperJavaAPI操作-查询节点" class="headerlink" title="4.4)ZookeeperJavaAPI操作-查询节点"></a>4.4)ZookeeperJavaAPI操作-查询节点</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 查询节点：</span></span><br><span class="line"><span class="comment">* 1. 查询数据：get: getData().forPath()</span></span><br><span class="line"><span class="comment">* 2. 查询子节点： ls: getChildren().forPath()</span></span><br><span class="line"><span class="comment">* 3. 查询节点状态信息：ls -s:getData().storingStatIn(状态对象).forPath()</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testGet1</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">//1. 查询数据：get</span></span><br><span class="line">    <span class="type">byte</span>[] data = client.getData().forPath(<span class="string">&quot;/app1&quot;</span>);</span><br><span class="line">    System.out.println(<span class="keyword">new</span> <span class="title class_">String</span>(data));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testGet2</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">// 2. 查询子节点： ls</span></span><br><span class="line">    List&lt;String&gt; path = client.getChildren().forPath(<span class="string">&quot;/&quot;</span>);</span><br><span class="line">    System.out.println(path);</span><br><span class="line">&#125;</span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testGet3</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="type">Stat</span> <span class="variable">status</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Stat</span>();</span><br><span class="line">    System.out.println(status);</span><br><span class="line">    <span class="comment">//3. 查询节点状态信息：ls -s</span></span><br><span class="line">    client.getData().storingStatIn(status).forPath(<span class="string">&quot;/app1&quot;</span>);</span><br><span class="line">    System.out.println(status);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="4-5-Zookeeper-JavaAPI操作-修改节点"><a href="#4-5-Zookeeper-JavaAPI操作-修改节点" class="headerlink" title="4.5)Zookeeper JavaAPI操作-修改节点"></a>4.5)Zookeeper JavaAPI操作-修改节点</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 修改数据</span></span><br><span class="line"><span class="comment">* 1. 基本修改数据：setData().forPath()</span></span><br><span class="line"><span class="comment">* 2. 根据版本修改: setData().withVersion().forPath()</span></span><br><span class="line"><span class="comment">* * version 是通过查询出来的。目的就是为了让其他客户端或者线程不干扰我。</span></span><br><span class="line"><span class="comment">*</span></span><br><span class="line"><span class="comment">* <span class="doctag">@throws</span> Exception</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testSet</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">	client.setData().forPath(<span class="string">&quot;/app1&quot;</span>, <span class="string">&quot;itcast&quot;</span>.getBytes());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testSetForVersion</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="type">Stat</span> <span class="variable">status</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Stat</span>();</span><br><span class="line">    <span class="comment">//3. 查询节点状态信息：ls -s</span></span><br><span class="line">    client.getData().storingStatIn(status).forPath(<span class="string">&quot;/app1&quot;</span>);</span><br><span class="line">    <span class="type">int</span> <span class="variable">version</span> <span class="operator">=</span> status.getVersion();<span class="comment">//查询出来的 3</span></span><br><span class="line">    System.out.println(version);</span><br><span class="line">    client.setData().withVersion(version).forPath(<span class="string">&quot;/app1&quot;</span>, <span class="string">&quot;hehe&quot;</span>.getBytes());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="4-6-Zookeeper-JavaAPI操作-删除节点"><a href="#4-6-Zookeeper-JavaAPI操作-删除节点" class="headerlink" title="4.6)Zookeeper JavaAPI操作-删除节点"></a>4.6)Zookeeper JavaAPI操作-删除节点</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 删除节点： delete deleteall</span></span><br><span class="line"><span class="comment">* 1. 删除单个节点:delete().forPath(&quot;/app1&quot;);</span></span><br><span class="line"><span class="comment">* 2. 删除带有子节点的节点:delete().deletingChildrenIfNeeded().forPath(&quot;/app1&quot;);</span></span><br><span class="line"><span class="comment">* 3. 必须成功的删除:为了防止网络抖动。本质就是重试。  client.delete().guaranteed().forPath(&quot;/app2&quot;);</span></span><br><span class="line"><span class="comment">* 4. 回调：inBackground</span></span><br><span class="line"><span class="comment">* <span class="doctag">@throws</span> Exception</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testDelete</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">// 1. 删除单个节点</span></span><br><span class="line">    client.delete().forPath(<span class="string">&quot;/app1&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testDelete2</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">//2. 删除带有子节点的节点</span></span><br><span class="line">    client.delete().deletingChildrenIfNeeded().forPath(<span class="string">&quot;/app4&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testDelete3</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">//3. 必须成功的删除</span></span><br><span class="line">    client.delete().guaranteed().forPath(<span class="string">&quot;/app2&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testDelete4</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">//4. 回调</span></span><br><span class="line">    client.delete().guaranteed().inBackground(<span class="keyword">new</span> <span class="title class_">BackgroundCallback</span>()&#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">processResult</span><span class="params">(CuratorFramework client, CuratorEvent event)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;我被删除了~&quot;</span>);</span><br><span class="line">            System.out.println(event);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forPath(<span class="string">&quot;/app1&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="4-7-Zookeeper-JavaAPI操作-Watch监听概述"><a href="#4-7-Zookeeper-JavaAPI操作-Watch监听概述" class="headerlink" title="4.7)Zookeeper JavaAPI操作-Watch监听概述"></a>4.7)Zookeeper JavaAPI操作-Watch监听概述</h3><p>•ZooKeeper 允许用户在指定节点上注册一些Watcher，并且在一些特定事件触发的时候，ZooKeeper 服务端会将事件通知到感兴趣的客户端上去，该机制是 ZooKeeper 实现分布式协调服务的重要特性。</p>
<p>•ZooKeeper 中引入了Watcher机制来实现了发布&#x2F;订阅功能能，能够让多个订阅者同时监听某一个对象，当一个对象自身状态变化时，会通知所有订阅者。</p>
<p>•ZooKeeper 原生支持通过注册Watcher来进行事件监听，但是其使用并不是特别方便</p>
<p>​    需要开发人员自己反复注册Watcher，比较繁琐。</p>
<p>•Curator引入了 Cache 来实现对 ZooKeeper 服务端事件的监听。</p>
<p>•ZooKeeper提供了三种Watcher：</p>
<p>•NodeCache : 只是监听某一个特定的节点</p>
<p>•PathChildrenCache : 监控一个ZNode的子节点. </p>
<p>•TreeCache : 可以监控整个树上的所有节点，类似于PathChildrenCache和NodeCache的组合</p>
<p><img src="/myl-mm/assets%5C1592057429708.png" alt="1592057429708"></p>
<h3 id="4-8Zookeeper-JavaAPI操作-Watch监听-NodeCache"><a href="#4-8Zookeeper-JavaAPI操作-Watch监听-NodeCache" class="headerlink" title="4.8Zookeeper JavaAPI操作-Watch监听-NodeCache"></a>4.8Zookeeper JavaAPI操作-Watch监听-NodeCache</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 演示 NodeCache：给指定一个节点注册监听器</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testNodeCache</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">//1. 创建NodeCache对象</span></span><br><span class="line">    <span class="keyword">final</span> <span class="type">NodeCache</span> <span class="variable">nodeCache</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">NodeCache</span>(client,<span class="string">&quot;/app1&quot;</span>);</span><br><span class="line">    <span class="comment">//2. 注册监听</span></span><br><span class="line">   	nodeCache.getListenable().addListener(<span class="keyword">new</span> <span class="title class_">NodeCacheListener</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">nodeChanged</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;节点变化了~&quot;</span>);</span><br><span class="line">            <span class="comment">//获取修改节点后的数据</span></span><br><span class="line">            <span class="type">byte</span>[] data = nodeCache.getCurrentData().getData();</span><br><span class="line">            System.out.println(<span class="keyword">new</span> <span class="title class_">String</span>(data));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">    	<span class="comment">//3. 开启监听.如果设置为true，则开启监听是，加载缓冲数据</span></span><br><span class="line">    	nodeCache.start(<span class="literal">true</span>);</span><br><span class="line">    	<span class="keyword">while</span> (<span class="literal">true</span>)&#123;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="4-9-Zookeeper-JavaAPI操作-Watch监听-PathChildrenCache"><a href="#4-9-Zookeeper-JavaAPI操作-Watch监听-PathChildrenCache" class="headerlink" title="4.9)Zookeeper JavaAPI操作-Watch监听-PathChildrenCache"></a><strong>4.9)Zookeeper</strong> JavaAPI操作-Watch监听-PathChildrenCache</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testPathChildrenCache</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">//1.创建监听对象</span></span><br><span class="line">    <span class="type">PathChildrenCache</span> <span class="variable">pathChildrenCache</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">PathChildrenCache</span>(client,<span class="string">&quot;/app2&quot;</span>,<span class="literal">true</span>);</span><br><span class="line">    <span class="comment">//2. 绑定监听器</span></span><br><span class="line">    pathChildrenCache.getListenable().addListener(<span class="keyword">new</span> <span class="title class_">PathChildrenCacheListener</span>() &#123;    			<span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">childEvent</span><span class="params">(CuratorFramework client, PathChildrenCacheEvent event)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;子节点变化了~&quot;</span>);</span><br><span class="line">            System.out.println(event);</span><br><span class="line">            <span class="comment">//监听子节点的数据变更，并且拿到变更后的数据</span></span><br><span class="line">            <span class="comment">//1.获取类型</span></span><br><span class="line">            PathChildrenCacheEvent.<span class="type">Type</span> <span class="variable">type</span> <span class="operator">=</span> event.getType();</span><br><span class="line">            <span class="comment">//2.判断类型是否是update</span></span><br><span class="line">            <span class="keyword">if</span>(type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED))&#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;数据变了！！！&quot;</span>);</span><br><span class="line">                <span class="type">byte</span>[] data = event.getData().getData();</span><br><span class="line">                System.out.println(<span class="keyword">new</span> <span class="title class_">String</span>(data));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    <span class="comment">//3. 开启</span></span><br><span class="line">    pathChildrenCache.start();</span><br><span class="line">    <span class="keyword">while</span> (<span class="literal">true</span>)&#123;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="4-10-Zookeeper-JavaAPI操作-Watch监听-TreeCache"><a href="#4-10-Zookeeper-JavaAPI操作-Watch监听-TreeCache" class="headerlink" title="4.10)Zookeeper JavaAPI操作-Watch监听-TreeCache"></a><strong>4.10)Zookeeper</strong> JavaAPI操作-Watch监听-TreeCache</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 演示 TreeCache：监听某个节点自己和所有子节点们</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testTreeCache</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">//1. 创建监听器</span></span><br><span class="line">    <span class="type">TreeCache</span> <span class="variable">treeCache</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">TreeCache</span>(client,<span class="string">&quot;/app2&quot;</span>);</span><br><span class="line">    <span class="comment">//2. 注册监听</span></span><br><span class="line">    treeCache.getListenable().addListener(<span class="keyword">new</span> <span class="title class_">TreeCacheListener</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">childEvent</span><span class="params">(CuratorFramework client, TreeCacheEvent event)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;节点变化了&quot;</span>);</span><br><span class="line">            System.out.println(event);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    <span class="comment">//3. 开启</span></span><br><span class="line">    treeCache.start();</span><br><span class="line">    <span class="keyword">while</span> (<span class="literal">true</span>)&#123;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="4-11-Zookeeper分布式锁-概念"><a href="#4-11-Zookeeper分布式锁-概念" class="headerlink" title="4.11)Zookeeper分布式锁-概念"></a>4.11)Zookeeper分布式锁-概念</h3><p>•在我们进行单机应用开发，涉及并发同步的时候，我们往往采用synchronized或者Lock的方式来解决多线程间的代码同步问题，这时多线程的运行都是在同一个JVM之下，没有任何问题。</p>
<p>•但当我们的应用是分布式集群工作的情况下，属于多JVM下的工作环境，跨JVM之间已经无法通过多线程的锁解决同步问题。</p>
<p>•那么就需要一种更加高级的锁机制，来处理种跨机器的进程之间的数据同步问题——这就是分布式锁。</p>
<p><img src="/myl-mm/assets%5C1592057871141.png" alt="1592057871141"></p>
<h3 id="4-12-Zookeeper-分布式锁-zookeeper分布式锁原理"><a href="#4-12-Zookeeper-分布式锁-zookeeper分布式锁原理" class="headerlink" title="4.12)Zookeeper 分布式锁-zookeeper分布式锁原理"></a><strong>4.12)Zookeeper</strong> 分布式锁-zookeeper分布式锁原理</h3><p>•核心思想：当客户端要获取锁，则创建节点，使用完锁，则删除该节点。</p>
<p>1.客户端获取锁时，在lock节点下创建临时顺序节点。</p>
<p>2.然后获取lock下面的所有子节点，客户端获取到所有的子节点之后，如果发现自己创建的子节点序号最小，那么就认为该客户端获取到了锁。使用完锁后，将该节点删除。</p>
<p>3.如果发现自己创建的节点并非lock所有子节点中最小的，说明自己还没有获取到锁，此时客户端需要找到比自己小的那个节点，同时对其注册事件监听器，监听删除事件。</p>
<p>4.如果发现比自己小的那个节点被删除，则客户端的</p>
<p>​    Watcher会收到相应通知，此时再次判断自己创建的节点</p>
<p>​    是否是lock子节点中序号最小的，如果是则获取到了锁，</p>
<p>​    如果不是则重复以上步骤继续获取到比自己小的一个节点</p>
<p>​    并注册监听。</p>
<p><img src="/myl-mm/assets%5C1592057925831.png" alt="1592057925831"></p>
<h3 id="4-13-Zookeeper-分布式锁-模拟12306售票案例"><a href="#4-13-Zookeeper-分布式锁-模拟12306售票案例" class="headerlink" title="4.13)Zookeeper 分布式锁-模拟12306售票案例"></a><strong>4.13)Zookeeper</strong> 分布式锁-模拟12306售票案例</h3><p><strong>Curator实现分布式锁API</strong></p>
<ul>
<li><p>在Curator中有五种锁方案：</p>
<ul>
<li><p>InterProcessSemaphoreMutex：分布式排它锁（非可重入锁）</p>
</li>
<li><p>InterProcessMutex：分布式可重入排它锁</p>
</li>
<li><p>InterProcessReadWriteLock：分布式读写锁</p>
</li>
<li><p>InterProcessMultiLock：将多个锁作为单个实体管理的容器</p>
</li>
<li><p>InterProcessSemaphoreV2：共享信号量</p>
</li>
</ul>
</li>
</ul>
<p><img src="/myl-mm/assets%5C1592058017457.png" alt="1592058017457"></p>
<p>1,创建线程进行加锁设置</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Ticket12306</span> <span class="keyword">implements</span> <span class="title class_">Runnable</span>&#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> <span class="variable">tickets</span> <span class="operator">=</span> <span class="number">10</span>;<span class="comment">//数据库的票数</span></span><br><span class="line">    <span class="keyword">private</span> InterProcessMutex lock ;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">while</span>(<span class="literal">true</span>)&#123;</span><br><span class="line">            <span class="comment">//获取锁</span></span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">            lock.acquire(<span class="number">3</span>, TimeUnit.SECONDS);</span><br><span class="line">                <span class="keyword">if</span>(tickets &gt; <span class="number">0</span>)&#123;</span><br><span class="line">                    System.out.println(Thread.currentThread()+<span class="string">&quot;:&quot;</span>+tickets);</span><br><span class="line">                    Thread.sleep(<span class="number">100</span>);</span><br><span class="line">                    tickets--;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">                e.printStackTrace();</span><br><span class="line">            &#125;<span class="keyword">finally</span> &#123;</span><br><span class="line">                <span class="comment">//释放锁</span></span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    lock.release();</span><br><span class="line">                &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">                    e.printStackTrace();</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>2,创建连接，并且初始化锁</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="title function_">Ticket12306</span><span class="params">()</span>&#123;</span><br><span class="line">    <span class="comment">//重试策略</span></span><br><span class="line">    <span class="type">RetryPolicy</span> <span class="variable">retryPolicy</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ExponentialBackoffRetry</span>(<span class="number">3000</span>, <span class="number">10</span>);</span><br><span class="line">    <span class="comment">//2.第二种方式</span></span><br><span class="line">    <span class="comment">//CuratorFrameworkFactory.builder();</span></span><br><span class="line">    <span class="type">CuratorFramework</span> <span class="variable">client</span> <span class="operator">=</span> CuratorFrameworkFactory.builder()</span><br><span class="line">        .connectString(<span class="string">&quot;192.168.149.135:2181&quot;</span>)</span><br><span class="line">        .sessionTimeoutMs(<span class="number">60</span> * <span class="number">1000</span>)</span><br><span class="line">        .connectionTimeoutMs(<span class="number">15</span> * <span class="number">1000</span>)</span><br><span class="line">        .retryPolicy(retryPolicy)</span><br><span class="line">        .build();</span><br><span class="line">    <span class="comment">//开启连接</span></span><br><span class="line">    client.start();</span><br><span class="line">    lock = <span class="keyword">new</span> <span class="title class_">InterProcessMutex</span>(client,<span class="string">&quot;/lock&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>3,运行多个线程进行测试</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">LockTest</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">Ticket12306</span> <span class="variable">ticket12306</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Ticket12306</span>();</span><br><span class="line">        <span class="comment">//创建客户端</span></span><br><span class="line">        <span class="type">Thread</span> <span class="variable">t1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Thread</span>(ticket12306,<span class="string">&quot;携程&quot;</span>);</span><br><span class="line">        <span class="type">Thread</span> <span class="variable">t2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Thread</span>(ticket12306,<span class="string">&quot;飞猪&quot;</span>);</span><br><span class="line">        t1.start();</span><br><span class="line">        t2.start();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="5-ZooKeeper-集群搭建"><a href="#5-ZooKeeper-集群搭建" class="headerlink" title="5)ZooKeeper 集群搭建"></a>5)ZooKeeper 集群搭建</h2><h3 id="5-1-Zookeeper集群介绍"><a href="#5-1-Zookeeper集群介绍" class="headerlink" title="5.1)Zookeeper集群介绍"></a><strong>5.1)Zookeeper</strong>集群介绍</h3><p>Leader选举：</p>
<p>•Serverid：服务器ID</p>
<p>  比如有三台服务器，编号分别是1,2,3。</p>
<p>  编号越大在选择算法中的权重越大。</p>
<p>•Zxid：数据ID</p>
<p>  服务器中存放的最大数据ID.值越大说明数据  越新，在选举算法中数据越新权重越大。</p>
<p>•在Leader选举的过程中，如果某台ZooKeeper</p>
<p>​    获得了超过半数的选票，</p>
<p>​    则此ZooKeeper就可以成为Leader了。</p>
<h3 id="5-2-搭建要求"><a href="#5-2-搭建要求" class="headerlink" title="5.2)搭建要求"></a>5.2)搭建要求</h3><p>真实的集群是需要部署在不同的服务器上的，但是在我们测试时同时启动很多个虚拟机内存会吃不消，所以我们通常会搭建<strong>伪集群</strong>，也就是把所有的服务都搭建在一台虚拟机上，用端口进行区分。</p>
<p>我们这里要求搭建一个三个节点的Zookeeper集群（伪集群）。</p>
<h3 id="5-3-准备工作"><a href="#5-3-准备工作" class="headerlink" title="5.3)准备工作"></a><strong>5.3)准备工作</strong></h3><p>重新部署一台虚拟机作为我们搭建集群的测试服务器。</p>
<p>（1）安装JDK  【此步骤省略】。</p>
<p>（2）Zookeeper压缩包上传到服务器<br>（3）将Zookeeper解压 ，建立&#x2F;usr&#x2F;local&#x2F;zookeeper-cluster目录，将解压后的Zookeeper复制到以下三个目录</p>
<p>&#x2F;usr&#x2F;local&#x2F;zookeeper-cluster&#x2F;zookeeper-1</p>
<p>&#x2F;usr&#x2F;local&#x2F;zookeeper-cluster&#x2F;zookeeper-2</p>
<p>&#x2F;usr&#x2F;local&#x2F;zookeeper-cluster&#x2F;zookeeper-3</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">[root@localhost ~]# mkdir /usr/local/zookeeper-cluster</span><br><span class="line">[root@localhost ~]# cp -r  apache-zookeeper-3.5.6-bin /usr/local/zookeeper-cluster/zookeeper-1</span><br><span class="line">[root@localhost ~]# cp -r  apache-zookeeper-3.5.6-bin /usr/local/zookeeper-cluster/zookeeper-2</span><br><span class="line">[root@localhost ~]# cp -r  apache-zookeeper-3.5.6-bin /usr/local/zookeeper-cluster/zookeeper-3</span><br></pre></td></tr></table></figure>

<p>（4）创建data目录 ，并且将 conf下zoo_sample.cfg 文件改名为 zoo.cfg</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">mkdir /usr/local/zookeeper-cluster/zookeeper-1/data</span><br><span class="line">mkdir /usr/local/zookeeper-cluster/zookeeper-2/data</span><br><span class="line">mkdir /usr/local/zookeeper-cluster/zookeeper-3/data</span><br><span class="line"></span><br><span class="line">mv  /usr/local/zookeeper-cluster/zookeeper-1/conf/zoo_sample.cfg  /usr/local/zookeeper-cluster/zookeeper-1/conf/zoo.cfg</span><br><span class="line">mv  /usr/local/zookeeper-cluster/zookeeper-2/conf/zoo_sample.cfg  /usr/local/zookeeper-cluster/zookeeper-2/conf/zoo.cfg</span><br><span class="line">mv  /usr/local/zookeeper-cluster/zookeeper-3/conf/zoo_sample.cfg  /usr/local/zookeeper-cluster/zookeeper-3/conf/zoo.cfg</span><br></pre></td></tr></table></figure>





<p>（5） 配置每一个Zookeeper 的dataDir 和 clientPort 分别为2181  2182  2183</p>
<p>修改&#x2F;usr&#x2F;local&#x2F;zookeeper-cluster&#x2F;zookeeper-1&#x2F;conf&#x2F;zoo.cfg</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">vim /usr/local/zookeeper-cluster/zookeeper-1/conf/zoo.cfg</span><br><span class="line"></span><br><span class="line">clientPort=2181</span><br><span class="line">dataDir=/usr/local/zookeeper-cluster/zookeeper-1/data</span><br></pre></td></tr></table></figure>

<p>修改&#x2F;usr&#x2F;local&#x2F;zookeeper-cluster&#x2F;zookeeper-2&#x2F;conf&#x2F;zoo.cfg</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">vim /usr/local/zookeeper-cluster/zookeeper-2/conf/zoo.cfg</span><br><span class="line"></span><br><span class="line">clientPort=2182</span><br><span class="line">dataDir=/usr/local/zookeeper-cluster/zookeeper-2/data</span><br></pre></td></tr></table></figure>

<p>修改&#x2F;usr&#x2F;local&#x2F;zookeeper-cluster&#x2F;zookeeper-3&#x2F;conf&#x2F;zoo.cfg</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">vim /usr/local/zookeeper-cluster/zookeeper-3/conf/zoo.cfg</span><br><span class="line"></span><br><span class="line">clientPort=2183</span><br><span class="line">dataDir=/usr/local/zookeeper-cluster/zookeeper-3/data</span><br></pre></td></tr></table></figure>



<h3 id="5-4-配置集群"><a href="#5-4-配置集群" class="headerlink" title="5.4)配置集群"></a><strong>5.4)配置集群</strong></h3><p>（1）在每个zookeeper的 data 目录下创建一个 myid 文件，内容分别是1、2、3 。这个文件就是记录每个服务器的ID</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">echo 1 &gt;/usr/local/zookeeper-cluster/zookeeper-1/data/myid</span><br><span class="line">echo 2 &gt;/usr/local/zookeeper-cluster/zookeeper-2/data/myid</span><br><span class="line">echo 3 &gt;/usr/local/zookeeper-cluster/zookeeper-3/data/myid</span><br></pre></td></tr></table></figure>





<p>（2）在每一个zookeeper 的 zoo.cfg配置客户端访问端口（clientPort）和集群服务器IP列表。</p>
<p>集群服务器IP列表如下</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">vim /usr/local/zookeeper-cluster/zookeeper-1/conf/zoo.cfg</span><br><span class="line">vim /usr/local/zookeeper-cluster/zookeeper-2/conf/zoo.cfg</span><br><span class="line">vim /usr/local/zookeeper-cluster/zookeeper-3/conf/zoo.cfg</span><br><span class="line"></span><br><span class="line">server.1=192.168.149.135:2881:3881</span><br><span class="line">server.2=192.168.149.135:2882:3882</span><br><span class="line">server.3=192.168.149.135:2883:3883</span><br></pre></td></tr></table></figure>

<p>解释：server.服务器ID&#x3D;服务器IP地址：服务器之间通信端口：服务器之间投票选举端口</p>
<h3 id="5-5-启动集群"><a href="#5-5-启动集群" class="headerlink" title="5.5)启动集群"></a><strong>5.5)启动集群</strong></h3><p>启动集群就是分别启动每个实例。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/usr/local/zookeeper-cluster/zookeeper-1/bin/zkServer.sh start</span><br><span class="line">/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh start</span><br><span class="line">/usr/local/zookeeper-cluster/zookeeper-3/bin/zkServer.sh start</span><br></pre></td></tr></table></figure>



<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%B5%84%E6%96%99/images/wps11.jpg" alt="img"> </p>
<p>启动后我们查询一下每个实例的运行状态</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/usr/local/zookeeper-cluster/zookeeper-1/bin/zkServer.sh status</span><br><span class="line">/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh status</span><br><span class="line">/usr/local/zookeeper-cluster/zookeeper-3/bin/zkServer.sh status</span><br></pre></td></tr></table></figure>



<p>先查询第一个服务</p>
<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%B5%84%E6%96%99/images/wps12.jpg" alt="img"> </p>
<p>Mode为follower表示是<strong>跟随者</strong>（从）</p>
<p>再查询第二个服务Mod 为leader表示是<strong>领导者</strong>（主）</p>
<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%B5%84%E6%96%99/images/wps13.jpg" alt="img"> </p>
<p>查询第三个为跟随者（从）</p>
<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%B5%84%E6%96%99/images/wps14.jpg" alt="img"> </p>
<h3 id="5-6-模拟集群异常"><a href="#5-6-模拟集群异常" class="headerlink" title="5.6)模拟集群异常"></a><strong>5.6)模拟集群异常</strong></h3><p>（1）首先我们先测试如果是从服务器挂掉，会怎么样</p>
<p>把3号服务器停掉，观察1号和2号，发现状态并没有变化</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">/usr/local/zookeeper-cluster/zookeeper-3/bin/zkServer.sh stop</span><br><span class="line"></span><br><span class="line">/usr/local/zookeeper-cluster/zookeeper-1/bin/zkServer.sh status</span><br><span class="line">/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh status</span><br></pre></td></tr></table></figure>

<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%B5%84%E6%96%99/images/wps15.jpg" alt="img"> </p>
<p>由此得出结论，3个节点的集群，从服务器挂掉，集群正常</p>
<p>（2）我们再把1号服务器（从服务器）也停掉，查看2号（主服务器）的状态，发现已经停止运行了。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/usr/local/zookeeper-cluster/zookeeper-1/bin/zkServer.sh stop</span><br><span class="line"></span><br><span class="line">/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh status</span><br></pre></td></tr></table></figure>



<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%B5%84%E6%96%99/images/wps16.jpg" alt="img"> </p>
<p>由此得出结论，3个节点的集群，2个从服务器都挂掉，主服务器也无法运行。因为可运行的机器没有超过集群总数量的半数。</p>
<p>（3）我们再次把1号服务器启动起来，发现2号服务器又开始正常工作了。而且依然是领导者。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/usr/local/zookeeper-cluster/zookeeper-1/bin/zkServer.sh start</span><br><span class="line"></span><br><span class="line">/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh status</span><br></pre></td></tr></table></figure>



<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%B5%84%E6%96%99/images/wps17.jpg" alt="img"> </p>
<p>（4）我们把3号服务器也启动起来，把2号服务器停掉,停掉后观察1号和3号的状态。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">/usr/local/zookeeper-cluster/zookeeper-3/bin/zkServer.sh start</span><br><span class="line">/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh stop</span><br><span class="line"></span><br><span class="line">/usr/local/zookeeper-cluster/zookeeper-1/bin/zkServer.sh status</span><br><span class="line">/usr/local/zookeeper-cluster/zookeeper-3/bin/zkServer.sh status</span><br></pre></td></tr></table></figure>



<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%B5%84%E6%96%99/images/wps18.jpg" alt="img"> </p>
<p>发现新的leader产生了~  </p>
<p>由此我们得出结论，当集群中的主服务器挂了，集群中的其他服务器会自动进行选举状态，然后产生新得leader </p>
<p>（5）我们再次测试，当我们把2号服务器重新启动起来启动后，会发生什么？2号服务器会再次成为新的领导吗？我们看结果</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh start</span><br><span class="line"></span><br><span class="line">/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh status</span><br><span class="line">/usr/local/zookeeper-cluster/zookeeper-3/bin/zkServer.sh status</span><br></pre></td></tr></table></figure>



<p><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%B5%84%E6%96%99/images/wps19.jpg" alt="img"><img src="G:/2020%E6%96%B0%E8%AF%BE%E7%A8%8B/zookeeper-2020-%E8%AF%BE%E4%BB%B6/%E8%B5%84%E6%96%99/images/wps20.jpg" alt="img"> </p>
<p>我们会发现，2号服务器启动后依然是跟随者（从服务器），3号服务器依然是领导者（主服务器），没有撼动3号服务器的领导地位。</p>
<p>由此我们得出结论，当领导者产生后，再次有新服务器加入集群，不会影响到现任领导者。</p>
<h2 id="6-Zookeeper-核心理论"><a href="#6-Zookeeper-核心理论" class="headerlink" title="6)Zookeeper 核心理论"></a>6)Zookeeper 核心理论</h2><p><strong>Zookeepe集群角色</strong></p>
<p>在ZooKeeper集群服中务中有三个角色：</p>
<p>•Leader 领导者 ：          </p>
<p>​	1. 处理事务请求</p>
<p>​	2. 集群内部各服务器的调度者</p>
<p>•Follower 跟随者 ：</p>
<p>​	1. 处理客户端非事务请求，转发事务请求给Leader服务器</p>
<p>​	2. 参与Leader选举投票</p>
<p>•Observer 观察者：</p>
<pre><code>1. 处理客户端非事务请求，转发事务请求给Leader服务器
</code></pre>
<p><img src="/myl-mm/assets%5C1592058451822.png" alt="1592058451822"></p>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="https://gitee.com/tgreen/myl-mm.git">myl</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://gitee.com/tgreen/myl-mm.git/2022/05/09/zookeeper%E8%AE%B2%E4%B9%89md/">https://gitee.com/tgreen/myl-mm.git/2022/05/09/zookeeper%E8%AE%B2%E4%B9%89md/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://gitee.com/tgreen/myl-mm.git" target="_blank">阿毛的博客</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/myl-mm/tags/ZooKeeper/">ZooKeeper</a></div><div class="post_share"><div class="social-share" data-image="https://itcast-haoke-myl.oss-cn-beijing.aliyuncs.com/images/2022/04/13/cat1.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/gh/overtrue/share.js@master/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/myl-mm/2022/05/09/RabbitMQ%20%E8%AE%B2%E4%B9%89/"><img class="prev-cover" src="https://itcast-haoke-myl.oss-cn-beijing.aliyuncs.com/images/2022/04/13/cat1.jpg" onerror="onerror=null;src='/myl-mm/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">RabbitMQ</div></div></a></div><div class="next-post pull-right"><a href="/myl-mm/2022/05/09/Dubbo/"><img class="next-cover" src="https://itcast-haoke-myl.oss-cn-beijing.aliyuncs.com/images/2022/04/13/cat1.jpg" onerror="onerror=null;src='/myl-mm/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">Dubbo</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/myl-mm/2022/05/09/Zookeeper%E5%AE%89%E8%A3%85/" title="ZOOKeeper安装"><img class="cover" src="https://itcast-haoke-myl.oss-cn-beijing.aliyuncs.com/images/2022/04/13/cat1.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-05-09</div><div class="title">ZOOKeeper安装</div></div></a></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png" onerror="this.onerror=null;this.src='/myl-mm/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">myl</div><div class="author-info__description"></div></div><div class="card-info-data site-data is-center"><a href="/myl-mm/archives/"><div class="headline">文章</div><div class="length-num">22</div></a><a href="/myl-mm/tags/"><div class="headline">标签</div><div class="length-num">11</div></a><a href="/myl-mm/categories/"><div class="headline">分类</div><div class="length-num">7</div></a></div><a id="card-info-btn" href="https://gitee.com/tgreen/"><i class="fab fa-github"></i><span>Follow Me</span></a></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">欢迎观看，又来一个！</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#Zookeeper"><span class="toc-number">1.</span> <span class="toc-text">Zookeeper</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-%E5%88%9D%E8%AF%86-Zookeeper"><span class="toc-number">1.1.</span> <span class="toc-text">1)初识 Zookeeper</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-1-Zookeeper%E6%A6%82%E5%BF%B5"><span class="toc-number">1.1.1.</span> <span class="toc-text">1.1)Zookeeper概念</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-ZooKeeper-%E5%AE%89%E8%A3%85%E4%B8%8E%E9%85%8D%E7%BD%AE"><span class="toc-number">1.2.</span> <span class="toc-text">2)ZooKeeper 安装与配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#2-1-%E4%B8%8B%E8%BD%BD%E5%AE%89%E8%A3%85"><span class="toc-number">1.2.1.</span> <span class="toc-text">2.1) 下载安装</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#2-1-1%E3%80%81%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87"><span class="toc-number">1.2.1.1.</span> <span class="toc-text">2.1.1、环境准备</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-1-2%E3%80%81%E4%B8%8A%E4%BC%A0"><span class="toc-number">1.2.1.2.</span> <span class="toc-text">2.1.2、上传</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-1-3%E3%80%81%E8%A7%A3%E5%8E%8B"><span class="toc-number">1.2.1.3.</span> <span class="toc-text">2.1.3、解压</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-2-%E9%85%8D%E7%BD%AE%E5%90%AF%E5%8A%A8"><span class="toc-number">1.2.2.</span> <span class="toc-text">2.2) 配置启动</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#2-2-1%E3%80%81%E9%85%8D%E7%BD%AEzoo-cfg"><span class="toc-number">1.2.2.1.</span> <span class="toc-text">2.2.1、配置zoo.cfg</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-2-2%E3%80%81%E5%90%AF%E5%8A%A8ZooKeeper"><span class="toc-number">1.2.2.2.</span> <span class="toc-text">2.2.2、启动ZooKeeper</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link"><span class="toc-number">1.2.3.</span> <span class="toc-text"></span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-ZooKeeper-%E5%91%BD%E4%BB%A4%E6%93%8D%E4%BD%9C"><span class="toc-number">1.3.</span> <span class="toc-text">3)ZooKeeper 命令操作</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#3-1-Zookeeper%E5%91%BD%E4%BB%A4%E6%93%8D%E4%BD%9C%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B"><span class="toc-number">1.3.1.</span> <span class="toc-text">3.1)Zookeeper命令操作数据模型</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-2-Zookeeper%E5%91%BD%E4%BB%A4%E6%93%8D%E4%BD%9C%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%91%BD%E4%BB%A4"><span class="toc-number">1.3.2.</span> <span class="toc-text">3.2)Zookeeper命令操作服务端命令</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-3-Zookeeper%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4"><span class="toc-number">1.3.3.</span> <span class="toc-text">3.3)Zookeeper客户端常用命令</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-4-%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%91%BD%E4%BB%A4-%E5%88%9B%E5%BB%BA%E4%B8%B4%E6%97%B6%E6%9C%89%E5%BA%8F%E8%8A%82%E7%82%B9"><span class="toc-number">1.3.4.</span> <span class="toc-text">3.4)客户端命令-创建临时有序节点</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-ZooKeeper-JavaAPI-%E6%93%8D%E4%BD%9C"><span class="toc-number">1.4.</span> <span class="toc-text">4)ZooKeeper JavaAPI 操作</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#4-1-urator%E4%BB%8B%E7%BB%8D"><span class="toc-number">1.4.1.</span> <span class="toc-text">4.1)urator介绍</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-2-JavaAPI%E6%93%8D%E4%BD%9C%E5%BB%BA%E7%AB%8B%E8%BF%9E%E6%8E%A5"><span class="toc-number">1.4.2.</span> <span class="toc-text">4.2)JavaAPI操作建立连接</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-3-Zookeeper-JavaAPI%E6%93%8D%E4%BD%9C-%E5%88%9B%E5%BB%BA%E8%8A%82%E7%82%B9"><span class="toc-number">1.4.3.</span> <span class="toc-text">4.3)Zookeeper JavaAPI操作-创建节点</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-4-ZookeeperJavaAPI%E6%93%8D%E4%BD%9C-%E6%9F%A5%E8%AF%A2%E8%8A%82%E7%82%B9"><span class="toc-number">1.4.4.</span> <span class="toc-text">4.4)ZookeeperJavaAPI操作-查询节点</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-5-Zookeeper-JavaAPI%E6%93%8D%E4%BD%9C-%E4%BF%AE%E6%94%B9%E8%8A%82%E7%82%B9"><span class="toc-number">1.4.5.</span> <span class="toc-text">4.5)Zookeeper JavaAPI操作-修改节点</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-6-Zookeeper-JavaAPI%E6%93%8D%E4%BD%9C-%E5%88%A0%E9%99%A4%E8%8A%82%E7%82%B9"><span class="toc-number">1.4.6.</span> <span class="toc-text">4.6)Zookeeper JavaAPI操作-删除节点</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-7-Zookeeper-JavaAPI%E6%93%8D%E4%BD%9C-Watch%E7%9B%91%E5%90%AC%E6%A6%82%E8%BF%B0"><span class="toc-number">1.4.7.</span> <span class="toc-text">4.7)Zookeeper JavaAPI操作-Watch监听概述</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-8Zookeeper-JavaAPI%E6%93%8D%E4%BD%9C-Watch%E7%9B%91%E5%90%AC-NodeCache"><span class="toc-number">1.4.8.</span> <span class="toc-text">4.8Zookeeper JavaAPI操作-Watch监听-NodeCache</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-9-Zookeeper-JavaAPI%E6%93%8D%E4%BD%9C-Watch%E7%9B%91%E5%90%AC-PathChildrenCache"><span class="toc-number">1.4.9.</span> <span class="toc-text">4.9)Zookeeper JavaAPI操作-Watch监听-PathChildrenCache</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-10-Zookeeper-JavaAPI%E6%93%8D%E4%BD%9C-Watch%E7%9B%91%E5%90%AC-TreeCache"><span class="toc-number">1.4.10.</span> <span class="toc-text">4.10)Zookeeper JavaAPI操作-Watch监听-TreeCache</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-11-Zookeeper%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81-%E6%A6%82%E5%BF%B5"><span class="toc-number">1.4.11.</span> <span class="toc-text">4.11)Zookeeper分布式锁-概念</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-12-Zookeeper-%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81-zookeeper%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81%E5%8E%9F%E7%90%86"><span class="toc-number">1.4.12.</span> <span class="toc-text">4.12)Zookeeper 分布式锁-zookeeper分布式锁原理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-13-Zookeeper-%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81-%E6%A8%A1%E6%8B%9F12306%E5%94%AE%E7%A5%A8%E6%A1%88%E4%BE%8B"><span class="toc-number">1.4.13.</span> <span class="toc-text">4.13)Zookeeper 分布式锁-模拟12306售票案例</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-ZooKeeper-%E9%9B%86%E7%BE%A4%E6%90%AD%E5%BB%BA"><span class="toc-number">1.5.</span> <span class="toc-text">5)ZooKeeper 集群搭建</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#5-1-Zookeeper%E9%9B%86%E7%BE%A4%E4%BB%8B%E7%BB%8D"><span class="toc-number">1.5.1.</span> <span class="toc-text">5.1)Zookeeper集群介绍</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-2-%E6%90%AD%E5%BB%BA%E8%A6%81%E6%B1%82"><span class="toc-number">1.5.2.</span> <span class="toc-text">5.2)搭建要求</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-3-%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C"><span class="toc-number">1.5.3.</span> <span class="toc-text">5.3)准备工作</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-4-%E9%85%8D%E7%BD%AE%E9%9B%86%E7%BE%A4"><span class="toc-number">1.5.4.</span> <span class="toc-text">5.4)配置集群</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-5-%E5%90%AF%E5%8A%A8%E9%9B%86%E7%BE%A4"><span class="toc-number">1.5.5.</span> <span class="toc-text">5.5)启动集群</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-6-%E6%A8%A1%E6%8B%9F%E9%9B%86%E7%BE%A4%E5%BC%82%E5%B8%B8"><span class="toc-number">1.5.6.</span> <span class="toc-text">5.6)模拟集群异常</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#6-Zookeeper-%E6%A0%B8%E5%BF%83%E7%90%86%E8%AE%BA"><span class="toc-number">1.6.</span> <span class="toc-text">6)Zookeeper 核心理论</span></a></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/myl-mm/2022/05/09/RabbitMQ%20Windows%20%E5%AE%89%E8%A3%85/" title="RabbitMQ Windows 安装"><img src="https://itcast-haoke-myl.oss-cn-beijing.aliyuncs.com/images/2022/04/13/cat1.jpg" onerror="this.onerror=null;this.src='/myl-mm/img/404.jpg'" alt="RabbitMQ Windows 安装"/></a><div class="content"><a class="title" href="/myl-mm/2022/05/09/RabbitMQ%20Windows%20%E5%AE%89%E8%A3%85/" title="RabbitMQ Windows 安装">RabbitMQ Windows 安装</a><time datetime="2022-05-09T09:04:30.600Z" title="发表于 2022-05-09 17:04:30">2022-05-09</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/myl-mm/2022/05/09/gateway%E5%86%85%E7%BD%AE%E8%BF%87%E6%BB%A4%E5%99%A8%E5%B7%A5%E5%8E%82/" title="Spring Cloud Gateway 内置的过滤器工厂"><img src="https://itcast-haoke-myl.oss-cn-beijing.aliyuncs.com/images/2022/04/13/cat1.jpg" onerror="this.onerror=null;this.src='/myl-mm/img/404.jpg'" alt="Spring Cloud Gateway 内置的过滤器工厂"/></a><div class="content"><a class="title" href="/myl-mm/2022/05/09/gateway%E5%86%85%E7%BD%AE%E8%BF%87%E6%BB%A4%E5%99%A8%E5%B7%A5%E5%8E%82/" title="Spring Cloud Gateway 内置的过滤器工厂">Spring Cloud Gateway 内置的过滤器工厂</a><time datetime="2022-05-09T09:04:19.065Z" title="发表于 2022-05-09 17:04:19">2022-05-09</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/myl-mm/2022/05/09/Turbine%E6%90%AD%E5%BB%BA%E6%AD%A5%E9%AA%A4/" title="Turbine"><img src="https://itcast-haoke-myl.oss-cn-beijing.aliyuncs.com/images/2022/04/13/cat1.jpg" onerror="this.onerror=null;this.src='/myl-mm/img/404.jpg'" alt="Turbine"/></a><div class="content"><a class="title" href="/myl-mm/2022/05/09/Turbine%E6%90%AD%E5%BB%BA%E6%AD%A5%E9%AA%A4/" title="Turbine">Turbine</a><time datetime="2022-05-09T09:04:13.000Z" title="发表于 2022-05-09 17:04:13">2022-05-09</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/myl-mm/2022/05/09/Eureka%20%E5%85%A8%E9%83%A8%E9%85%8D%E7%BD%AE%20/" title="Euraka配置详解"><img src="https://itcast-haoke-myl.oss-cn-beijing.aliyuncs.com/images/2022/04/13/cat1.jpg" onerror="this.onerror=null;this.src='/myl-mm/img/404.jpg'" alt="Euraka配置详解"/></a><div class="content"><a class="title" href="/myl-mm/2022/05/09/Eureka%20%E5%85%A8%E9%83%A8%E9%85%8D%E7%BD%AE%20/" title="Euraka配置详解">Euraka配置详解</a><time datetime="2022-05-09T09:03:49.699Z" title="发表于 2022-05-09 17:03:49">2022-05-09</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/myl-mm/2022/05/09/01-Springboot-day01/" title="springBootday01"><img src="https://itcast-haoke-myl.oss-cn-beijing.aliyuncs.com/images/2022/04/13/cat1.jpg" onerror="this.onerror=null;this.src='/myl-mm/img/404.jpg'" alt="springBootday01"/></a><div class="content"><a class="title" href="/myl-mm/2022/05/09/01-Springboot-day01/" title="springBootday01">springBootday01</a><time datetime="2022-05-09T09:03:15.476Z" title="发表于 2022-05-09 17:03:15">2022-05-09</time></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2022 By myl</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/myl-mm/js/utils.js"></script><script src="/myl-mm/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.js"></script><div class="js-pjax"></div><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>